#include <iostream>
#include <sstream>
#include <vector>
#include <list>
#include <queue>
#include <utility>

#define MAX(x,y) ((x) > (y) ? (x) : (y))
 
using namespace std;

class Grafo {
	private:
		int m_nodos; // C = |V|
		list< pair<int, int> > *m_aristas;
		vector< list<int> > *m_adyacencias; // lista de adyacencias
		vector< int > *m_grados; // grado de cada nodo
	
	public:
		Grafo(int n) { // Complejidad O(C)
			// O(C)
			m_nodos = n;
			
			// O(1)
			m_aristas = new list< pair<int, int> > ();
			
			// O(C)
			m_adyacencias = new vector< list<int> > (n, list<int> () );
			
			// O(C)
			m_grados = new vector<int> (n,0);
		}
		
		
		
		~Grafo() {
			delete m_aristas;
			delete m_adyacencias;
			delete m_grados;
		}
		
		void ponerArtista(int nodo1, int nodo2) {
			(*m_aristas).push_back( make_pair(nodo1, nodo2) );
			
			(*m_adyacencias)[nodo1-1].push_back(nodo2);
			if (nodo1 != nodo2)
				(*m_adyacencias)[nodo2-1].push_back(nodo1);
			
			(*m_grados)[nodo1 - 1]++;
			(*m_grados)[nodo2 - 1]++;
		}
		
		int nodos() const {
			return m_nodos;
		}
		
		list<int> adyacencias(int nodo) const {
			return (*m_adyacencias)[nodo-1];
		}
		
		list< pair<int, int> > aristas() {
			return (*m_aristas);
		}
		

		// DETERMINA SI EL GRAFO ES CONEXO, USANDO BFS
		
		bool esConexo() {
			vector<bool> visitados(m_nodos, false);
			queue<int> nodos_por_recorrer;
			
			int nodo=1;
			// Descarta los nodos aislados
			// Busca el primer nodo con adyacente
			while( (*m_grados)[nodo - 1] == 0)
				nodo++;
				
			visitados[nodo-1] = true;
			list<int> vecinos = (*m_adyacencias)[nodo-1];
			for(list<int>::iterator it = vecinos.begin(); it != vecinos.end(); it++) {
				if((*it) == nodo)
					continue;
				else
					nodos_por_recorrer.push(*it);
			}
			
			//cerr << candidato << endl;
			
			while(!nodos_por_recorrer.empty()) {
				nodo = nodos_por_recorrer.front();
				nodos_por_recorrer.pop();
				
				if(visitados[nodo-1])
					continue;
				
				visitados[nodo-1] = true;

				//cerr << nodo << endl;
					
				list<int> vecinos = (*m_adyacencias)[nodo-1];
				for(list<int>::iterator it = vecinos.begin(); it != vecinos.end(); it++) {
					if((*it) == nodo)
						continue;
					else
						nodos_por_recorrer.push(*it);
				}
			}

			//cerr << endl << endl;
			
			/*for(vector<int>::iterator it2 = visitados.begin(); it2 != visitados.end(); it2++) {
				cerr << *it2 << " ";
			}*/
			
			bool todos_visitados = true;
			for(int i = 0; i < m_nodos && todos_visitados; i++) {
				//cerr << "nodo " << i << ": " << (visitados[i] ? "si" : "no") << endl;
				if ( (*m_grados)[i] > 0)
					todos_visitados &= visitados[i];
			}
		
			return todos_visitados;
		}

		
		
		// DETERMINA SI EL GRAFO ES EULERIANO
		
		bool esEuleriano() { // O(N)
			// 1. Todos los nodos tienen grado par
			for(vector<int>::iterator it = m_grados->begin(); it != m_grados->end(); it++)
				if((*it) % 2 != 0)
					return false;
			// 2. Salvo nodos aislados, el grafo es conexo
			return esConexo();
			
		}
		
		
		// DEVUELVE EL CICLO EULERIANO (una lista de aristas)
		
		list< pair<int, int> > circuitoEuleriano() {
			// O(1) + O(1)
			list< pair<int, int> > circuito_euleriano;
			list< pair<pair<int, int>, bool> > aristas_visitadas;
			
			// O(C)
			vector< list< pair<pair<int, int>, bool> * > > adyacencias (m_nodos, list< pair<pair<int, int>, bool> * > ());
			vector<int> grados(*m_grados);
			
			// O(N)
			for(list< pair<int, int> >::iterator it = m_aristas->begin(); it != m_aristas->end(); it++) {
				aristas_visitadas.push_back( make_pair(*it, false) ); // O(1)
				pair< pair<int, int>, bool > *arista_insertada = &aristas_visitadas.back(); // O(1)
				
				if ((*it).first == (*it).second)
					adyacencias[(*it).first - 1].push_back(arista_insertada); // O(1)
				else {
					adyacencias[(*it).first - 1].push_back(arista_insertada); // O(1)
					adyacencias[(*it).second - 1].push_back(arista_insertada); // O(1)
				}
			}
			
			// O(1)
			queue< pair<int, list< pair<int, int> >::iterator > > circuitos; // Cicuitos < nodo, posicion donde empieza el circuito dentro del circuito euleriano>
			
			// Empezamos siempre con el primer nodo con adyacencias
			int nodo=1;
			while( (*m_grados)[nodo - 1] == 0) 
				nodo++;
			circuitos.push( make_pair(nodo, circuito_euleriano.begin()) );
			
			// O(N) Creo que es 2N, ya que las aristas están dos veces por cada nodo, pero igual sigue siendo O(N)
			while( !circuitos.empty() ) {
				
				// Tomamos el siguiente nodo que aún tiene adyacencias: nodo
				pair< int, list< pair<int, int> >::iterator> temp = circuitos.front();
				circuitos.pop();		
				
				int nodo = temp.first;
				// Tomamos la posición de la lista de aristas, en donde insertaremos un nuevo circuito
				list< pair<int, int> >::iterator it   = temp.second;
				
				int actual = nodo;
				
				bool armadoUnCircuito = false;	
				
				
				// mientras no se haya formado un circuito (nodo -.....- nodo)
				while(!armadoUnCircuito) {
					
					if(grados[actual - 1] > 0) {
						pair< pair<int, int>, bool > *arista_temp = 0;
						// Obtenemos la siguiente arista
						do {
							arista_temp = adyacencias[actual - 1].front();
							adyacencias[actual - 1].pop_front();
						} while( (*arista_temp).second && (grados[actual - 1] > 0) );
						
						if( (*arista_temp).second ) {
							// Si entre por acá quiere decir que este nodo no tenía aristas que
							// no hayan sido ya visitadas, por lo tanto el circuito termina acá.
							armadoUnCircuito = true;
						} else {
							// Este nodo tiene al menos una arista no visitada
							
							// Decrementamos en 1 el grado a ambos vértices
							grados[(arista_temp->first).first - 1]--;
							grados[(arista_temp->first).second - 1]--;
							
							if(grados[actual - 1] > 0) {
								// Al nodo todavía le quedan aristas por revisar, por lo tanto es
								// posible que desde él se forme otro circuito.Así que lo insertamos
								// en la cola de circuitos.
								circuitos.push( make_pair(actual, it) );
							}
							
							// Marcamos la arista como visitada
							(*arista_temp).second = true;
											
							// Agregamos la arista al circuito euleriano
							circuito_euleriano.insert(it, (*arista_temp).first);
							
							// Ponemos como siguiente nodo el que elemento de la arista que no es este nodo.
							actual = (*arista_temp).first.first == actual ? (*arista_temp).first.second : (*arista_temp).first.first;
							
							// Aumentamos la posición donde se insertará el siguiente elemento
							it--;
							
							if(nodo == actual)	armadoUnCircuito = true;
							
						}
					} else {
						armadoUnCircuito = true;
					}
				}
			}
			
			return circuito_euleriano;
		}
		
		friend ostream& operator<<(ostream &salida, const Grafo &g) {
			for(int i = 0; i < g.m_nodos; i++) {
				salida << "* " << i+1 << ": ";
				
				list<int> aristas = (*g.m_adyacencias)[i];
				for(list<int>::iterator it = aristas.begin(); it != aristas.end(); it++) {
					salida << "(" << i+1 << ", " << *it << ") ";
				}
				salida << endl;
			}
			
			return salida;
		}
};

string resolver(const list< pair< int, int > > &cuentas) {
	// Obtenemos el color más grande que tienen las cuentas, y con esto la cantidad
	// de nodos que va a tener el grafo de nuestro modelo.
	int max = 0;
	for(list< pair<int, int> >::const_iterator it = cuentas.begin(); it != cuentas.end(); it++) {
		int temp_max = MAX((*it).first, (*it).second);
		max = MAX(max, temp_max);
	}
	int colores = max;
	
	Grafo *g = new Grafo(colores);
	for(list< pair<int, int> >::const_iterator it = cuentas.begin(); it != cuentas.end(); it++) {
		g->ponerArtista((*it).first, (*it).second);
	}
	
	bool esEuleriano = g->esEuleriano();
	stringstream resultado;
	
	if(esEuleriano) {
		list< pair<int, int> > circuito_euleriano = g->circuitoEuleriano();
		
		if(!circuito_euleriano.empty()) {
			int cuenta_union = 0;
			pair<int, int> temp;
			
			list< pair<int, int> >::iterator it = circuito_euleriano.begin();
			temp = *it;
			
			it++;
			temp = (temp.first == (*it).first ? make_pair(temp.second, temp.first) : (temp.first == (*it).second ? make_pair(temp.second, temp.first) : make_pair(temp.first, temp.second)));
			cuenta_union = temp.second;
			
			resultado << temp.first << " " << temp.second << std::endl;
			
			for(; it != circuito_euleriano.end(); it++) {
				temp = *it;
				temp = (temp.first == cuenta_union ? make_pair(temp.first, temp.second) : make_pair(temp.second, temp.first));
				cuenta_union = temp.second;
				
				resultado << temp.first << " " << temp.second << std::endl;
			}
		}
	} else {
		resultado << "some beads may be lost" << std::endl;
	}
	
	//cerr << *g << endl;
	//cerr << resultado.str() << endl;
	
	delete g;
	return resultado.str();
}

void resolverDesdeEntrada( istream &entrada, ostream &salida ) {
	int T = 0;
	entrada >> T;
	
	for(int entradas = 0; entradas < T; entradas++) {
		int N = 0;
		list< pair <int, int> > cuentas;
		
		// Leemos la entrada
		entrada >> N;
		for (int i = 0; i < N; i++) {
			int color1, color2;
			
			entrada >> color1 >> color2;
			cuentas.push_back( make_pair(color1, color2) );
		}
		
		salida << "Case #" << (entradas + 1) << endl;
		salida << resolver(cuentas);
		
		if(entradas != (T - 1))
			cout << endl;
	}
}

#ifdef ONLINE_JUDGE
int main() {
	resolverDesdeEntrada( cin, cout );
	return 0;
}
#endif